package com.sunny.design.flyweight.general;

import java.util.HashMap;
import java.util.Map;

/**
 * 享元模式（Flyweight Pattern）
 *  享元模式又称为轻量级模式，是对象池的一种实现。类似于线程池，线程池可以避免不停的创建和销毁多个对象，消耗性能。
 *  提供了减少对象数量从而改善应用所需的对象结构的方式。
 *  其宗旨是共享细粒度对象，将多个对同一对象的访问集中起来，不必为每个访问者创建一个单独的对象，以此来降低内存的消耗，属于结构型模式。
 *
 *  享元模式把一个对象的状态分成内部状态和外部状态，内部状态即是不变的，外部状态是变化的；然后通过共享不变的部分，达到减少对象数量并节约内存的目的
 *  享元模式模式的本质是缓存共享对象，降低内存消耗。
 *
 * 享元模式有三个参与角色：
 *  抽象享元角色（Flyweight）：享元对象抽象基类或者接口，同时定义出对象的外部状态和内部状态的接口或实现；
 *  具体享元角色（ConcreteFlyweight）：实现抽象角色定义的业务。该角色的内部状态处理应该与环境无关，不能出现会有一个操作改变内部状态，同时修改了外部状态；
 *  享元工厂（FlyweightFactory）：负责管理享元对象池和创建享元对象。
 *
 * 适用场景：
 *  1、常常应用于系统底层的开发，以便解决系统的性能问题。
 *  2、系统有大量相似对象、需要缓冲池的场景。
 *
 * 优点:
 *  1、减少对象的创建，降低内存中对象的数量，降低系统的内存，提高效率;
 *  2、减少内存之外的其他资源占用。
 *
 * 缺点：
 *  1、关注内、外部状态、关注线程安全问题；
 *  2、使系统、程序的逻辑复杂化。
 */
// 享元工厂
public class FlyweightFactory {
    private static Map<String, IFlyweight> pool = new HashMap<String, IFlyweight>();

    // 因为内部状态具备不变性，因此作为缓存的键
    public static IFlyweight getFlyweight(String intrinsicState) {
        if (!pool.containsKey(intrinsicState)) {
            IFlyweight flyweight = new ConcreteFlyweight(intrinsicState);
            pool.put(intrinsicState, flyweight);
        }
        return pool.get(intrinsicState);
    }
}